iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 10
0

20190926

前言

今天要介紹的是Swift中的Optional。通常我們的資料或是物件中,會有不存在的情況 (nil 或是想成 null)。
例如在一個變數中,型態為數字中的0,與沒有數字是不同意思,字串中的空字串,與沒有字串也是不同意思。所以,Swift中的Optional將優雅的解決這些問題,並且這也是Swift一大特色。

現在,我們馬上開始!

如何建立playground,請參考Day4的文章
https://ithelp.ithome.com.tw/articles/10217428

當Value Type遇到 Optional

一樣先來看看程式碼

// Optional
var number1: Int? = nil
number1 // nil
type(of: number1) // Optional<Int>.Type

var name: String? = "mike"
print(name) // Optional("mike")
  • 這邊可以看到Int後面加上一個問號?,就是Optional

  • 而Optional預設值可以給nil,如果是一般Int型別給nil,則會報錯

  • 在變數name直接取值,會得到結果Optional("mike"),而不是我們需要的字串"mike"

Optional 解開與使用

force-unwrap
直接使用驚嘆號!強制解開,如果沒有值的話,會爆出錯誤並且App會閃退。
因此除非很確定有值,或是先用if判斷,不然不建議使用這個方式

let number2: Optional<Int> = 1
let number3 = number2! + 1
number3 // 2

Optional Binding
這個算是非常使用的解開Optional方式

let luckyNumber: Int? = 7
let minNumber: Int? = Int.min

if let number1 = luckyNumber, let number2 = minNumber {
    print(number1)
    print(number2)
} else {
    print("error")
}
  • 使用if let來解開luckyNumber & minNumber
  • 如果解開失敗,就不會執行{}裡面的程式碼
  • 只有一開始要加上if let,後面直接加上let即可解開多個變數

Optional Chaining
如果變數有多階層,或是類別中的屬性,可以使用這個方式

let swiftImage = UIImage(named: "IT30_Swift")
let size = swiftImage?.size
size
  • swiftImage的型別為UIImage?
  • 取用size屬性時,如果swiftImage為nil,就不會往在取值,會直接回傳nil
  • 因此本例中的size為nil,如果swiftImage不為空時,才會取得size

Nil-Coalescing Operator

class Pet {
    var name: String = ""
    var age: Int = 0
    var hasBreeder: Optional<Bool> = nil
    init(name:String, age: Int, breeder: Bool? = nil) {
        self.name = name
        self.age = age
        self.hasBreeder = breeder
    }
}
let pat1 = Pet(name: "QQ", age: 3, breeder: true)
let hasBreeder = pat1.hasBreeder ?? false
  • 本例中有一個寵物QQ,並有一個主人mike
  • 我們不確定有沒有主人,因此使用兩個問號??,如果沒有主人預設就給 false

Guard with Optional

這個方式與if let的Optional Binding非常類似,但是有一些差異性,實務上也常常會使用。
一樣來看看程式碼

let isIT30Complete:Bool? = true
func getIT30Status(article: Int, isComplete: Bool?) -> Bool {
    guard let complete = isIT30Complete else {
        return false
    }
    return complete && article > 30
}
let finish = getIT30Status(article: 31, isComplete: true)
finish // true
  • 可以看到 guard 如果失敗,就會進入else內,可以直接return回傳

  • 使用guard let設定的變數,在同一個scope內都可存取,而if let只有{}大括弧內可存取

總結

在今天的文章裡,我們做了Optional的說明,也介紹了幾個解開Optional的方法。筆者在練習App的過程中,比較常使用的還是if let & guard let 這兩種方式。
今天的內容就到這邊,感謝讀者們的閱讀。


Github:

https://github.com/chiron-wang/IT30_11

參考資料與延伸閱讀

  1. 彼得潘的 Swift iOS App 開發問題解答集
    https://medium.com/%E5%BD%BC%E5%BE%97%E6%BD%98%E7%9A%84-swift-ios-app-%E9%96%8B%E7%99%BC%E5%95%8F%E9%A1%8C%E8%A7%A3%E7%AD%94%E9%9B%86

  2. iOS 13 & Swift 5 - The Complete iOS App Development Bootcamp - Angela Yu
    https://www.udemy.com/course/ios-13-app-development-bootcamp/

  3. 深入淺出 iPhone 開發 (使用 Swift4) - WeiWei
    https://www.udemy.com/course/iphone-swift4/

  4. 心智圖軟體Xmind
    https://www.xmind.net/

  5. 彼得潘的Swift程式設計入門
    https://www.tenlong.com.tw/products/9789572246573

  6. 《The Swift Programming Language》正體中文版
    https://tommy60703.gitbooks.io/swift-language-traditional-chinese/content/chapter2/01_The_Basics.html#floating-point_numbers

  7. Apple Developer Document
    https://developer.apple.com/documentation/swift/optional

[Optional相關參考]

  1. Swift的問號與驚嘆號:可有可無的 Optional
    https://www.appcoda.com.tw/swift-optional-intro/

  2. swift doc Optional
    https://docs.swift.org/swift-book/LanguageGuide/OptionalChaining.html

  3. Swift 學習筆記
    https://hugolu.gitbooks.io/learn-swift/content/Basic/Optional.html


上一篇
Day9 Closure
下一篇
Day11 流程控制
系列文
iOS App 實作開發新手村36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言